package org.fujene.structure;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * It contains terms like {@link java.util.ArrayList}, with a function to count
 * term frequencies.
 * 
 * @author Yusuke Fujisaka
 */
public class TermList implements Iterable<Term>, Collection<Term>{
	private Term[] terms;
	private int currentLength;
	private int called;

	public TermList(){
		this(10);
	}

	public TermList(int initial){
		terms = new Term[initial];
		currentLength = 0;
	}

	@Override
	public boolean add(Term term){
		int i;
		boolean found = false;

		for(i = 0; i < terms.length && terms[i] != null; i++)
			if (terms[i].equals(term)){
				found = true;
				synchronized(terms){
					terms[i].increment();
				}
			}

		if (!found){
			synchronized(terms){
				if (i >= terms.length)
				// 拡張
					terms = Arrays.copyOf(terms, (int)(1.5 * currentLength));
				terms[i] = term;
			}
			currentLength++;
		}
		return true;
	}

	public int size(){
		return currentLength;
	}

	public Term get(int index){
		if (index >= currentLength) return null;

		return terms[index];
	}

	@Override
	public Iterator<Term> iterator(){
		called = 0;
		return new Iterator<Term>(){
			@Override
			public boolean hasNext(){
				return called < currentLength;
			}

			@Override
			public Term next(){
				if (called < currentLength)
					return terms[called++];
				else throw new NoSuchElementException();
			}

			@Override
			public void remove(){
				throw new UnsupportedOperationException();
			}
		};
	}

	@Override
	public boolean isEmpty(){
		return currentLength == 0;
	}

	@Override
	public boolean contains(Object o){
		for(int i = 0; i < terms.length; i++){
			if (terms[i].equals(o)) return true;
		}
		return false;
	}

	@Override
	public Object[] toArray(){
		return Arrays.copyOf(terms, terms.length);
	}

	@SuppressWarnings("unchecked")
	@Override
	public <T>T[] toArray(T[] a){
		if (a instanceof Term[]) return (T[])Arrays.copyOf(terms, terms.length);

		return null;
	}

	@Override
	public boolean remove(Object o){
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean containsAll(Collection<?> c){
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean addAll(Collection<? extends Term> c){
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean removeAll(Collection<?> c){
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean retainAll(Collection<?> c){
		throw new UnsupportedOperationException();
	}

	@Override
	public void clear(){
		// いったん消して復活
		terms = null;

		terms = new Term[10];
		currentLength = 0;

	}
}
